package org.example.gxpt.filter;

import com.alibaba.fastjson.JSONObject;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.example.gxpt.common.constant.*;
import org.example.gxpt.common.properties.JwtProperties;
import org.example.gxpt.common.utils.JwtUtil;
import org.example.gxpt.pojo.userdetails.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;

@Component
@Slf4j
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private JwtProperties jwtProperties;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        log.info("请求url:{}",request.getRequestURL());

        //获取token
        String token = request.getHeader("token");
        String path = request.getRequestURL().toString();
        if (!StringUtils.hasText(token) || path.contains(LoginURLConstant.LOGIN_URL)) {

            //存储当前登录用户的角色信息，在UserDetailsServiceImpl中取出用于判断当前登录用户的角色，从对应的mapper中查询
            //放在service的login里面了
//            if (path.contains(LoginURLConstant.USER_LOGIN_URL)) LoginContext.setCurrentRole(LoginRoleConstant.LOGIN_USER);
//            else if (path.contains(LoginURLConstant.INSTRUMENT_ADMIN_LOGIN_URL)) LoginContext.setCurrentRole(LoginRoleConstant.INSTRUMENT_ADMIN);
//            else if (path.contains(LoginURLConstant.SHOWROOM_ADMIN_LOGIN_URL)) LoginContext.setCurrentRole(LoginRoleConstant.SHOWROOM_ADMIN);
//            else LoginContext.setCurrentRole(LoginRoleConstant.INSTRUMENT_ADMIN);
            //放行
            filterChain.doFilter(request, response);
            return;
        }
        //解析token
        String userid;
        String userRole;
        try {
            Claims claims = JwtUtil.parseJWT(jwtProperties.getSecretKey(), token);
            userid = claims.get(JwtClaimsConstant.ID).toString();
            userRole = claims.get(JwtClaimsConstant.ROLE).toString();
            log.info("jwt解析,userid:{},userRole:{}", userid, userRole);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("token非法");
        }
        //判断用户权限
        String redisKey;
        if (RoleConstant.USER.equals(userRole)) redisKey = RedisConstant.LOGIN_USER + userid;
        else if (RoleConstant.INSTRUMENT_ADMIN.equals(userRole)) redisKey = RedisConstant.LOGIN_INSTRUMENT_ADMIN + userid;
        else if (RoleConstant.SHOWROOM_ADMIN.equals(userRole)) redisKey = RedisConstant.LOGIN_SHOWROOM_ADMIN + userid;
        else if (RoleConstant.SYSTEM_ADMIN.equals(userRole)) redisKey = RedisConstant.LOGIN_SYSTEM_ADMIN + userid;
        else throw new RuntimeException("用户权限错误");
        JSONObject object = (JSONObject) redisTemplate.opsForValue().get(redisKey);
        if (Objects.isNull(object)) {
            throw new RuntimeException("用户未登录");
        }
        LoginUser loginUser = object.parseObject(object.toJSONString(), LoginUser.class);

        //存入SecurityContextHolder
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
        log.info("当前权限列表：{}", loginUser.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        //放行
        filterChain.doFilter(request, response);
    }
}
